package com.zw.admin.server.controller;

import com.alibaba.fastjson.JSONObject;
import com.zw.admin.server.dao.DeviceDao;
import com.zw.admin.server.dao.SpaceDeviceDao;
import com.zw.admin.server.dto.Device.AppInfo;
import com.zw.admin.server.dto.Device.DeviceType;
import com.zw.admin.server.dto.Device.Iot;
import com.zw.admin.server.model.Device;
import com.zw.admin.server.model.ResponseBean;
import com.zw.admin.server.page.table.PageTableHandler;
import com.zw.admin.server.page.table.PageTableRequest;
import com.zw.admin.server.page.table.PageTableResponse;
import com.zw.admin.server.service.DeviceService;
import com.zw.admin.server.service.SpaceService;
import com.zw.admin.server.utils.DeviceUtils;
import com.zw.admin.server.utils.HttpPost;
import com.zw.admin.server.utils.HttpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Api(tags = "设备")
@RestController
@RequestMapping("/device")
public class DeviceController {

    @Value("${baisheng.deviceUrl}")
    private String deviceUrl;
    @Value("${baisheng.apiToken}")
    private String apiToken;

    HttpUtil httpUtil = new HttpUtil();

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private SpaceService spaceService;


    /**
     * 获取 access_token
     */
    @ApiOperation(value = "获取 access_token")
    @GetMapping("/getAccessToken")
    public String getAccessToken() throws Exception {
        String getTokenUrl = "/api/v1/accessToken";
        HashMap param = new HashMap();
        param.put("api_token", apiToken);
        String result = HttpPost.https(deviceUrl + getTokenUrl, param);
        return (String) JSONObject.parseObject(result).get("accessToken");
    }

    /**
     * 获取应用列表
     */
    @ApiOperation(value = "获取应用列表")
    @GetMapping("/getAppList")
    public ArrayList<AppInfo> getAppList() throws Exception {
        String accessToken = getAccessToken();
        String getAppListUrl = "/api/v1/application/getAppList?access_token=" + accessToken;
        HashMap<Object, Object> map = new HashMap<Object, Object>();
        map.put("current", 1);
        map.put("rowCount", 2000);
        String result = HttpPost.https(deviceUrl + getAppListUrl, map);
        String data = JSONObject.parseObject(result).get("data").toString();
        String apps = JSONObject.parseObject(data).get("apps").toString();
        ArrayList<AppInfo> appInfoArray = (ArrayList<AppInfo>) JSONObject.parseArray(apps, AppInfo.class);
        return appInfoArray;
    }

    /**
     * 获取硬件类型列表
     */
    @ApiOperation(value = "获取硬件类型列表")
    @GetMapping("/getAllDevType")
    public ArrayList<DeviceType> getAllDevType() throws Exception {
        String accessToken = getAccessToken();
        String getAppListUrl = "/api/v1/device/getAllDevType?access_token=" + accessToken;
        HashMap<Object, Object> map = new HashMap<Object, Object>();
        map.put("tag", new ArrayList());
        map.put("current", 1);
        map.put("rowCount", 2000);
        String result = HttpPost.https(deviceUrl + getAppListUrl, map);
        String data = JSONObject.parseObject(result).get("data").toString();
        ArrayList<DeviceType> deviceTypes = (ArrayList<DeviceType>) JSONObject.parseArray(data, DeviceType.class);
        return deviceTypes;
    }

    /**
     * 从硬件平台获取硬件或设备状态
     */
    @ApiOperation(value = "从硬件平台获取硬件或设备状态")
    @GetMapping("/getStatus")
    public String getStatus() throws Exception {
        //获取温湿度传感器
        List<Iot> temperatureList = getTemperatureList();
        for (Iot temp : temperatureList) {
            Device device = new Device();
            DeviceUtils.Iot2Device(temp, device);
            device.setIotType("温湿度传感器");
            device.setTypeId("0dd1c51132088a48fbf96e623c18c12a0");
            deviceService.saveOrUpdate(device);
        }
        List types = new ArrayList<String>();
        //单路智能开关
        types.add("virtual-1598955190846074363");
        List<Iot> oneSwitch = getIotList(types);
        for (Iot temp : oneSwitch) {
            Device device = new Device();
            DeviceUtils.Iot2Device(temp, device);
            device.setIotType("单路智能开关");
            device.setTypeId("07cb95502326de2376339141372ef35c9");
            deviceService.saveOrUpdate(device);
        }
        types.remove(0);

        //双路智能开关
        types.add("virtual-1598955217549643631");
        List<Iot> twoSwitch = getIotList(types);
        for (Iot temp : twoSwitch) {
            Device device = new Device();
            DeviceUtils.Iot2Device(temp, device);
            device.setIotType("双路智能开关");
            device.setTypeId("0a0e80c8720c2b3775f1bdf13ca6d4768");
            deviceService.saveOrUpdate(device);
        }
        types.remove(0);

        //三路智能开关
        types.add("virtual-1598955239775596035");
        List<Iot> threeSwitch = getIotList(types);
        for (Iot temp : threeSwitch) {
            Device device = new Device();
            DeviceUtils.Iot2Device(temp, device);
            device.setIotType("三路智能开关");
            device.setTypeId("0f3f6e1c72e3a7a13dda206ee857958e4");
            deviceService.saveOrUpdate(device);
        }
        types.remove(0);
        //获取智能插座
        List<Iot> socketList = getSocketList();
        for (Iot temp : socketList) {
            Device device = new Device();
            DeviceUtils.Iot2Device(temp, device);
            device.setIotType("智能插座");
            device.setTypeId("055358d072d866d6ce58703585e23705e");
            deviceService.saveOrUpdate(device);
        }
        return "";
    }

    @GetMapping("/deviceList")
    @ApiOperation(value = "设备列表")
    public PageTableResponse deviceList(PageTableRequest request) {
        List<Device> spaceDevices = getSpaceDevice(request.getParams().get("treeData").toString());

        return new PageTableHandler(new PageTableHandler.CountHandler() {

            @Override
            public int count(PageTableRequest request) {
                //如果无树Id则返回全部，否则只返回该分类下所有
                if (request.getParams().get("treeData").toString().equals("")) {
                    return deviceService.count(request.getParams());
                } else {
                    getSpaceDevice(request.getParams().get("treeData").toString());
                    return spaceDevices == null ? 0 : spaceDevices.size();
                }
            }
        }, new PageTableHandler.ListHandler() {

            @Override
            public List<Device> list(PageTableRequest request) {
                //如果无树Id则返回全部，否则只返回该分类下所有
                if (request.getParams().get("treeData").toString().equals("")) {
                    return deviceService.list(request.getParams(), request.getOffset(), request.getLimit());
                } else {
                    int start = Integer.parseInt(request.getParams().get("start").toString());
                    int length = Integer.parseInt(request.getParams().get("length").toString());
                    int listSize = spaceDevices == null ? 0 : spaceDevices.size();
                    ArrayList<Device> resultList = new ArrayList<>();
                    for (int i = 0; i < length && i + start < listSize; i++) {
                        resultList.add(spaceDevices.get(i + start));
                    }
                    return resultList;
                }
            }
        }).handle(request);
    }

    @GetMapping("/getUnableDevice")
    @ApiOperation(value = "设备列表")
    public PageTableResponse getUnableDevice(PageTableRequest request) {
        List<Device> unableDevice = spaceService.getUnableDevice();

        return new PageTableHandler(new PageTableHandler.CountHandler() {

            @Override
            public int count(PageTableRequest request) {
                return unableDevice == null ? 0 : unableDevice.size();
            }
        }, new PageTableHandler.ListHandler() {

            @Override
            public List<Device> list(PageTableRequest request) {
                int start = Integer.parseInt(request.getParams().get("start").toString());
                int length = Integer.parseInt(request.getParams().get("length").toString());
                int listSize = unableDevice == null ? 0 : unableDevice.size();
                ArrayList<Device> resultList = new ArrayList<>();
                for (int i = 0; i < length && i + start < listSize; i++) {
                    resultList.add(unableDevice.get(i + start));
                }
                return resultList;
            }
        }).handle(request);
    }

    @GetMapping("/getSpaceDevice")
    @ApiOperation(value = "获取空间-设备关系")
    public List<Device> getSpaceDevice(String spaceId) {
        //获取该空间下所有子空间Id
        ArrayList<String> spaceIds = spaceService.getAllSubId(spaceId);
        //获取所有空间对应设备信息
        List<Device> spaceDevices = spaceService.getSpaceDevice(spaceIds);
        return spaceDevices;
    }

    @GetMapping("/getHomePageInfo")
    @ApiOperation(value = "获取首页数据信息")
    public String getHomePageInfo() throws Exception {

        List types = new ArrayList<String>();
        JSONObject result = new JSONObject();
        //获取温湿度传感器
        List<Iot> temperatureList = getTemperatureList();
        int tempOnlineNum = 0;
        for (Iot temp:temperatureList) {
            if (temp.getStates().equals("online")){
                tempOnlineNum ++;
            }
        }
        //获取智能开关
        List<Iot> switchList = getSwitchList();
        //获取智能插座
        List<Iot> socketList = getSocketList();
        int socketOnlineNum = 0;
        for (Iot socket:socketList) {
            if (socket.getStates().equals("online")){
                socketOnlineNum ++;
            }
        }

        //单路智能开关
        types.add("virtual-1598955190846074363");
        List<Iot> oneSwitch = getIotList(types);
        types.remove(0);
        int oneOnlineNum = 0;
        for (Iot iot:oneSwitch) {
            if (iot.getStates().equals("online")){
                oneOnlineNum ++;
            }
        }

        //双路智能开关
        types.add("virtual-1598955217549643631");
        List<Iot> twoSwitch = getIotList(types);
        types.remove(0);
        int twoOnlineNum = 0;
        for (Iot iot:twoSwitch) {
            if (iot.getStates().equals("online")){
                twoOnlineNum ++;
            }
        }

        //三路智能开关
        types.add("virtual-1598955239775596035");
        List<Iot> threeSwitch = getIotList(types);
        types.remove(0);
        int threeOnlineNum = 0;
        for (Iot iot:threeSwitch) {
            if (iot.getStates().equals("online")){
                threeOnlineNum ++;
            }
        }

        double temperature = 0.0; //总计温度
        double moisture = 0.0; //总计湿度
        double quantity = 0.0; //总计电量
        double max_quantity = 0.0; //最大用电量

        for (Iot temp : temperatureList) {
            temperature += temp.getData().getTEMPERATURE_1();
            moisture += temp.getData().getMOISTURE_1();
        }

        for (Iot socket : socketList) {
            quantity += socket.getData().getQUANTITY_1();
            if (socket.getData().getQUANTITY_1() > max_quantity) {
                max_quantity = socket.getData().getQUANTITY_1();
            }
        }

        result.put("temperatureNum", tempOnlineNum+"/"+temperatureList.size());
        result.put("socketNum", socketOnlineNum+"/"+socketList.size());
        result.put("oneSwitchNum", oneOnlineNum+"/"+oneSwitch.size());
        result.put("twoSwitchNum", twoOnlineNum+"/"+twoSwitch.size());
        result.put("threeSwitchNum", threeOnlineNum+"/"+threeSwitch.size());
        result.put("avg_temperature", temperature / temperatureList.size());
        result.put("avg_moisture", moisture / temperatureList.size());
        result.put("avg_quantity", quantity / socketList.size());
        result.put("max_quantity", max_quantity);
        return result.toJSONString();
    }

    @GetMapping("/iotList")
    @ApiOperation(value = "温湿度、照明、用电列表")
    public PageTableResponse iotList(PageTableRequest request) throws Exception {
        String pageType = request.getParams().get("pageType").toString();
        //获取温湿度传感器
        List<Iot> temperatureList = getTemperatureList();
        //获取智能开关
        List<Iot> switchList = getSwitchList();
        //获取智能插座
        List<Iot> socketList = getSocketList();

        List<Iot> handleList = new ArrayList<Iot>();

        if (pageType.equals("Temperature")) {
            handleList.addAll(temperatureList);
        } else if (pageType.equals("Socket")) {
            handleList.addAll(socketList);
        } else {
            handleList.addAll(switchList);
        }
        /**
         * 西北大学测试数据
         */
//        ArrayList<String> testType = new ArrayList<>();
//        testType.add("virtual-1594725245465482352");
//        testType.add("virtual-1594724996857640021");
//        testType.add("virtual-1595300893065927146");
//        testType.add("virtual-1594725013007298388");
//        testType.add("virtual-1594724983236501973");
//        testType.add("virtual-1595419196409230119");
//        handleList.addAll(getIotList(testType));

        return new PageTableHandler(new PageTableHandler.CountHandler() {
            @Override
            public int count(PageTableRequest request) {
                return handleList == null ? 0 : handleList.size();
            }
        }, new PageTableHandler.ListHandler() {

            @Override
            public List<Iot> list(PageTableRequest request) {
                int start = Integer.parseInt(request.getParams().get("start").toString());
                int length = Integer.parseInt(request.getParams().get("length").toString());
                int listSize = handleList == null ? 0 : handleList.size();
                ArrayList<Iot> resultList = new ArrayList<>();
                for (int i = 0; i < length && start + i < listSize; i++) {
                    resultList.add(handleList.get(start + i));
                }
                return resultList;
            }
        }).handle(request);
    }

    //获取所有温湿度传感器
    @GetMapping("/getTemperatureList")
    public List<Iot> getTemperatureList() throws Exception {
        List<String> types = new ArrayList<String>();
        types.add("virtual-1598955297545846647");
        return getIotList(types);
    }

    //获取所有开关
    @GetMapping("/getSwitchList")
    public List<Iot> getSwitchList() throws Exception {
        ArrayList<String> types = new ArrayList<String>();
        types.add("virtual-1598955239775596035");
        types.add("virtual-1598955190846074363");
        types.add("virtual-1598955217549643631");

        return getIotList(types);
    }

    //获取所有插座
    @GetMapping("/getSocketList")
    public List<Iot> getSocketList() throws Exception {
        ArrayList<String> types = new ArrayList<String>();
        types.add("virtual-1598955266763796604");

        return getIotList(types);
    }

    //获取所有设备信息
    @GetMapping("/getIotList")
    public List<Iot> getIotList(List<String> types) throws Exception {
        String accessToken = getAccessToken();
        String getDeviceUrl = "/api/v1/device/getStatus?access_token=" + accessToken;
        List<Iot> iotList = new ArrayList<>();

        JSONObject innerjson = new JSONObject();
        innerjson.put("all", true);
        HashMap<Object, Object> jsonData = new HashMap<Object, Object>();
        for (String type : types) {
            jsonData.put(type, innerjson);
        }

        String result = HttpPost.https(deviceUrl + getDeviceUrl, jsonData);

        //处理请求结果
        for (String type : types) {
            String tempJson = JSONObject.parseObject(result).get(type).toString();
            Object[] tempIndexs = JSONObject.parseObject(tempJson).keySet().toArray();
            for (int i = 0; i < tempIndexs.length; i++) {
                //解析为Temperature对象
                String currentTemp = JSONObject.parseObject(tempJson).get(tempIndexs[i]).toString();
                Iot iot = JSONObject.parseObject(currentTemp, Iot.class);
                iot.setIot_id(tempIndexs[i].toString());
                iotList.add(iot);
            }
        }
        return iotList;
    }

    //获取所有插座
    @GetMapping("/updateDeviceStates")
    public ResponseBean updateDeviceStates(String deviceId, String status) throws Exception {
        return deviceService.updateDeviceStates(deviceId, status);
    }

}
